home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1996 September / JCSM Shareware Collection (JCS Distribution) (September 1996).ISO / gameothr / wordy411.zip / PATTERN.C < prev    next >
C/C++ Source or Header  |  1995-12-17  |  9KB  |  342 lines

  1. /**************************************************************************/
  2. /*                       PATTERN-MATCH UTILITY                            */
  3. /*                                                                        */
  4. /*                                 M\Cooper                               */
  5. /*                        3425 Chestnut Ridge Rd.                         */
  6. /*                        Grantsville, MD 21536-9801                      */
  7. /*                        --------------------------                      */
  8. /*                        Email:  thegrendel@aol.com                      */
  9. /*                                                                        */
  10. /*                $2.00 to register the entire WORDY package                 */
  11. /*                                                                        */
  12. /**************************************************************************/
  13.  
  14. #include <conio.h>
  15. #include <ctype.h>
  16. #include "srch.h"
  17. //srch.h (source) is part of the WORDY package
  18.  
  19.  
  20. #define FILE_OPENING_ERROR 3
  21. #define FILENAME_MAXLEN 40
  22. #define CR "\n"
  23. #define FILE_SUFFIX ".pat"
  24. #define MAXLEN 30
  25. #define MAXWORDLEN 30
  26. #define LINE_LEN 80
  27. #define NOARGS 1
  28. #define INCREMENT 1
  29. #define SPACE ' '
  30. #define DBLBAR 205
  31. #define WILDCARD '?'
  32. //Wildcard character in command line, may be changed
  33. #define WRONG_SPECS 10
  34. #define PATTERN_TOO_LONG 20
  35.  
  36. #define BUFFERSIZE 8192
  37.  
  38. char ad[] =
  39. "PATTERN MATCH util. : M\\Cooper, 3425 Chestnut Ridge Rd., Grantsville, MD 21536";
  40.  
  41. typedef enum { FALSE, TRUE } Boolean;
  42. typedef enum { OFF, ON } Flag;
  43.  
  44. Boolean qualify( char *In );
  45. void getword( char *lset, char *filename );
  46. void center( char *strng );
  47. Boolean is_valid_word( char *Pattern, char *Word );
  48.  
  49. void main( int argc, char **argv )
  50. {
  51.  
  52.    char letterset [MAXLEN],
  53.         iset [5 * MAXLEN],
  54.         filename [FILENAME_MAXLEN];
  55.  
  56.      if( argc == NOARGS )
  57.         {
  58.         clrscr();
  59.         puts( "Enter a LETTER PATTERN to test [example 1231234] " );
  60.         gets( iset );
  61.      if( strlen( iset ) >= MAXWORDLEN - 2 )
  62.         {
  63.         printf( "\n\nPattern too long!\n" );
  64.         exit( PATTERN_TOO_LONG );
  65.         }
  66.      strcpy( letterset, iset );
  67.      strcpy( filename, "word.lst" );  //default
  68.         }
  69.      else
  70.      if( argc == NOARGS + 1 )
  71.        {
  72.        if( strlen( *(argv +1) ) >= MAXWORDLEN - 2 )
  73.           {
  74.           printf( "\n\nPattern too long!\n" );
  75.           exit( PATTERN_TOO_LONG);
  76.           }
  77.           strcpy( letterset, *(argv + 1) );
  78.        strcpy( filename, "word.lst" ); //default
  79.        }
  80.    else
  81.       {      
  82.        if( strlen( *(argv +1) ) >= MAXWORDLEN - 2 )
  83.           {
  84.           printf( "\n\nPattern too long!\n" );
  85.           exit( PATTERN_TOO_LONG);
  86.           }
  87.       strcpy( letterset, *(argv + 1) );
  88.       strcpy( filename, *(argv + 2) );
  89.       }
  90.  
  91.       if( !qualify( letterset ) )
  92.          {
  93.          printf( "\nInput to program must be a string of digits\n" );
  94.          printf( "in *ascending* order, beginning with '1'.\n" );
  95.          printf( "Previously used digits may be repeated.\n" );
  96.          exit( WRONG_SPECS );
  97.          }
  98.  
  99.      getword( letterset, filename );
  100. }
  101.  
  102.  
  103. /**********************************WORDTEST********************************/
  104. /*       Function tests if word is constructible from Letterset           */
  105. /*                 Args in: char *letterset, char *word                   */
  106. /*   Returns: error_flag == TRUE (1) if constructible, FALSE (0) if not   */
  107. /**************************************************************************/
  108.  
  109. Boolean wordtest( char *letterset, char *word )
  110. {
  111.     Boolean error_flag;
  112.     static char dup_lset[ MAXLEN ];
  113.     register unsigned int cnt = 0,
  114.                       u,
  115.                       v;
  116.  
  117.      strcpy( dup_lset, letterset );
  118.          
  119.      u = strlen( word );
  120.       v = strlen( letterset );
  121.  
  122.      while( ( *letterset == *word ) || *letterset == WILDCARD )
  123.         {
  124.         letterset++;
  125.         word++;
  126.         cnt++;
  127.         }
  128.  
  129.      if( u <= cnt && u == v )
  130.         error_flag = TRUE;
  131.      else
  132.         error_flag = FALSE;
  133.  
  134.  
  135.         return( error_flag );
  136. }
  137.  
  138. /**************************************************************************/
  139.  
  140. void getword( char *letter_set, char *filename )
  141. {
  142.  
  143.     char    l_set [ MAXLEN ],
  144.         word [ MAXLEN ],
  145.         tempstr [ MAXLEN + 1 ],
  146.         targetfile [ MAXLEN ],
  147.         bar [ LINE_LEN + 1 ],
  148.         double_bar [ LINE_LEN + 1 ],
  149.         messg [7];
  150.  
  151.     FILE *fptr,
  152.         *tfile;
  153.     int fnamelen;
  154.     long wcount = 0L;
  155.  
  156.        memset( bar, '*', LINE_LEN );
  157.        *( bar + LINE_LEN ) = NULL;
  158.        memset( double_bar, DBLBAR, LINE_LEN );
  159.        *( double_bar + LINE_LEN ) = NULL;
  160.  
  161.        /*************opening credits*************/
  162.        clrscr();
  163.        printf( double_bar );
  164.        strcpy( tempstr, ad );
  165.        center ( tempstr );
  166.        printf( tempstr );
  167.        printf( CR );
  168.        printf( double_bar );
  169.        printf( CR );
  170.        /****************************************/
  171.  
  172.  
  173.        strcpy ( l_set, letter_set );
  174.        strcat ( letter_set, CR );
  175.  
  176.        /*   Create name of file to store derived words in   */
  177.        /*********************************************************/
  178.        strcpy( targetfile, "matched.pat" );
  179.        /*********************************************************/
  180.  
  181.        if( !( fptr = fopen( filename, "rt" ) ) )
  182.          {
  183.          printf( "\7\7\7Cannot open word file %s!", filename );
  184.          exit( FILE_OPENING_ERROR );
  185.          }
  186.       if( setvbuf( fptr, NULL, _IOFBF, 2 * BUFFERSIZE ) )
  187.          exit( FILE_OPENING_ERROR + 1 );
  188.  
  189.        if( !( tfile = fopen( targetfile, "wt" ) ) )
  190.          {
  191.          printf( "\7\7\7Cannot open file to save words in!" );
  192.          exit ( FILE_OPENING_ERROR + 1 );
  193.          }
  194.       if( setvbuf( fptr, NULL, _IOFBF, BUFFERSIZE ) )
  195.          exit( FILE_OPENING_ERROR + 2 );
  196.  
  197.        /**************'Wait' Message************/
  198.        printf( CR CR );
  199.        printf( "WORKING...\n\n" );
  200.        printf( "This will take a few seconds...\n" );
  201.        printf( "Please be patient.\n\n" );
  202.        printf( "Now searching 100,000+ word file and writing file of valid words.\n\n" );
  203.        /*****************************************/
  204.  
  205.  
  206.  
  207.  
  208.  
  209.        sprintf( tempstr, "Words fitting the pattern of: %s\n", strupr( l_set ) );
  210.        center( tempstr );
  211.        fprintf( tfile, double_bar );
  212.       fprintf( tfile, CR );
  213.        fprintf( tfile, tempstr );
  214.        fprintf( tfile, double_bar );
  215.        fprintf( tfile, CR );
  216.  
  217.  
  218.          /*********************Main Loop*************/     
  219.           while( fgets( word, MAXLEN, fptr ) != NULL )
  220.  
  221.             if( is_valid_word( letter_set, word ) )
  222.                {
  223.                fprintf( tfile, "%s", word );
  224.                wcount++;
  225.                }
  226.           /*******************************************/
  227.  
  228.           if( wcount == INCREMENT )
  229.             strcpy( messg, "word" );
  230.           else
  231.             strcpy( messg, "words" );
  232.  
  233.           fprintf( tfile, bar );
  234.       fprintf( tfile, CR );
  235.           sprintf( tempstr, "%ld %s fit the pattern of %s.",
  236.                  wcount, messg, l_set );
  237.           center( tempstr );              
  238.           fprintf( tfile, tempstr );
  239.           fprintf( tfile, "\n\n" );
  240.  
  241.           center( ad );
  242.           fprintf( tfile, ad );
  243.  
  244.           fcloseall();
  245.  
  246.           sprintf( tempstr,
  247.                  "The file %s has %ld %s fitting the pattern of %s\7.",
  248.                  targetfile, wcount, messg, l_set );
  249.           center( tempstr );
  250.           printf( CR CR );
  251.           printf( tempstr );
  252.  
  253. }
  254.  
  255.  
  256.  
  257. void center( char *str )
  258. {
  259.    int padding;
  260.    char st [ LINE_LEN + INCREMENT ];
  261.  
  262.      padding = LINE_LEN / 2 - strlen( str ) / 2;
  263.      memset( st, SPACE, padding );
  264.      *( st + padding ) = NULL;  //Terminate string
  265.      strcat( st, str );
  266.      strcpy( str, st );
  267.  
  268.      return;
  269. }
  270.  
  271.  
  272. Boolean is_valid_word( char *pattern, char *word )
  273. {
  274.    char letter,
  275.         wd [MAXWORDLEN],
  276.         *index;
  277.    int wlen,
  278.        n,
  279.        cindex = 0;
  280.  
  281.       strcpy( wd, word );  //wd is working copy of word.
  282.       wlen = strlen( wd );
  283.  
  284.       for( n = 0; n < wlen; n++ )
  285.          {
  286.          letter = *( wd + n );
  287.          if( !isalpha( letter ) )
  288.             continue;
  289.          cindex++;
  290.          
  291.          while( NULL != ( index = strchr( wd, letter) ) )
  292.               *index = cindex + '0';
  293.          //Replace all instances of that letter with appropriate 'number'.
  294.          }
  295.  
  296.       if( !strcmp( wd, pattern ) )
  297.           return( TRUE );
  298.       else
  299.           return( FALSE );
  300.  
  301. }
  302.  
  303.  
  304. Boolean qualify( char *Input )
  305. {
  306.    size_t l;
  307.    int i,
  308.        n;
  309.    Flag F [MAXWORDLEN];
  310.       
  311.  
  312.       for( i = 2; i < MAXWORDLEN; i++ )
  313.          F[i] = OFF;
  314.       F[0] = F[1] = ON;
  315.       l = strlen ( Input );
  316.  
  317.       for( i = 0; i < l; i++ )
  318.          if( !isdigit( *(Input +i) ) )
  319.             return( FALSE );
  320.  
  321.       if( *Input != '1' )
  322.          return( FALSE );
  323.  
  324.       for( i = 1; i < l; i++ )
  325.          {
  326.          n = Input[i] - '0';
  327.  
  328.          if( F[n] )    //Number already used. Is o.k.
  329.             continue; 
  330.  
  331.          if( F[n-1] )  //Previous consecutive number already used. Is o.k.
  332.            {
  333.            F[n] = ON;
  334.            continue;
  335.            }
  336.         
  337.            return( FALSE ); //Default.
  338.            }
  339.  
  340.       return( TRUE );
  341. }
  342.